package com.ffcs.web.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * @ClassName: HttpSenderUtil
 * @Description: Http请求工具类
 * @Copyright: Copyright (c) 2010 FFCS All Rights Reserved
 * @Company 北京福富软件福州分公司
 * @author qushengzhi
 * @date Oct 23, 2012 1:41:58 PM
 * @version 1.00.00
 * @history:
 */
public class HttpSenderUtil {
	private static Logger logger = Logger
			.getLogger(HttpSenderUtil.class);
	/**
	 * 连接超时时间10s
	 */
	private final static int TIME_OUT = 60000;//ms
	/**
	 * 默认UTF-8编码
	 */
	private final static String CHARSET = "UTF-8";

	/**
	 * @Title: send4Post
	 * @Description: post请求
	 * @param :@param
	 *            url：请求地址
	 * @param :@param
	 *            reqStr:请求字符串
	 * @param :@return
	 * @param :@throws
	 *            Exception
	 * @return String 返回类型
	 * @author qushengzhi
	 * @date Oct 23, 2012 2:07:38 PM
	 */
	public static String send4Post(String url, String reqStr) throws Exception {
		String rspStr = null;// 返回字符串
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建post连接方法实例并设置参数
		 */
		PostMethod method = new PostMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 失败不重发
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
		method.addRequestHeader("User-Agent", "CS/Win8");
		method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//		method.addRequestHeader("Content-Type", "text/html");
		method.addRequestHeader("Accept-Encoding", "gzip");
		// 设置表单信息
		if (reqStr != null)
			method.setRequestEntity(new StringRequestEntity(reqStr, null,
					CHARSET));
		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				// 打印响应头信息
//				 Header[] header = method.getResponseHeaders();
//				 System.out.println("--------------post方法返回头信息开始--------------");
//				 for (int i = 0; i < header.length - 1; i++) {
//				 System.out.print(header[i]);
//				 }
//				 System.out.println("--------------post方法返回头信息结束--------------");
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				rspStr = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			throw new IOException("网络异常" );
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}

		return rspStr;
	}
	
	/**
	 * @Title: send4PostByJson 
	 * @Description: 使用json作为请求内容发送 post请求
	 * @param :@param url
	 * @param :@param reqStr
	 * @param :@return
	 * @param :@throws Exception
	 * @return String    返回类型  
	 * @author 蔡协鑫
	 * @date 2014年1月24日 下午4:46:27
	 */
	public static String send4PostByJson(String url, String reqStr) throws Exception {
		String rspStr = null;// 返回字符串
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建post连接方法实例并设置参数
		 */
		PostMethod method = new PostMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 失败不重发
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
		method.addRequestHeader("User-Agent", "CS/Win8");
		//发送json必须设置 Content-Type 为text/html
		method.addRequestHeader("Content-Type", "application/json");
		method.addRequestHeader("Content-Type", "text/html");
		method.addRequestHeader("Accept-Encoding", "gzip");
		// 设置表单信息
		if (reqStr != null)
			method.setRequestEntity(new StringRequestEntity(reqStr, null,
					CHARSET));
		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				// 打印响应头信息
				// Header[] header = method.getResponseHeaders();
				// System.out.println("--------------post方法返回头信息开始--------------");
				// for (int i = 0; i < header.length - 1; i++) {
				// System.out.print(header[i]);
				// }
				// System.out.println("--------------post方法返回头信息结束--------------");
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				rspStr = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}

		return rspStr;
	}

	public static String send4PostByJson(String url, String reqStr,Map<String,String> headParamsMap) throws Exception {
		String rspStr = null;// 返回字符串
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建post连接方法实例并设置参数
		 */
		PostMethod method = new PostMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 失败不重发
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
//		method.addRequestHeader("User-Agent", "CS/Win8");
		//发送json必须设置 Content-Type 为text/html
//		method.addRequestHeader("Content-Type", "application/json");
//		method.addRequestHeader("Content-Type", "text/html");
//		method.addRequestHeader("Accept-Encoding", "gzip");
//		method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		for(Map.Entry<String, String> entry:headParamsMap.entrySet()){    
			method.addRequestHeader(entry.getKey(), entry.getValue());  
		}   
		// 设置表单信息
		if (reqStr != null)
			method.setRequestEntity(new StringRequestEntity(reqStr, null,
					CHARSET));
		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				// 打印响应头信息
				// Header[] header = method.getResponseHeaders();
				// System.out.println("--------------post方法返回头信息开始--------------");
				// for (int i = 0; i < header.length - 1; i++) {
				// System.out.print(header[i]);
				// }
				// System.out.println("--------------post方法返回头信息结束--------------");
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				rspStr = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}

		return rspStr;
	}

	
	/**
	 * @Title: send4Get
	 * @Description: get方法
	 * @param :@param
	 *            url 请求地址
	 * @param :@param
	 *            request 请求参数
	 * @param :@return
	 * @param :@throws
	 *            Exception
	 * @return String 返回类型
	 * @author qushengzhi
	 * @date Oct 23, 2012 1:44:35 PM
	 */
	public static String send4Get(String url) throws Exception {
		String response = null;
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();// 创建HttpClient实例
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建get连接方法实例并设置参数
		 */
		GetMethod method = new GetMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 设置默认策略（在发生异常时候将自动重试0次）
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
		method.addRequestHeader("User-Agent", "CS/Win8");
		method.addRequestHeader("charset", "utf-8");
		method.addRequestHeader("Content-type",
				"application/x-www-form-urlencoded; charset=" + CHARSET);

		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				// 打印响应头信息
				Header[] header = method.getResponseHeaders();
				// System.out.println("--------------get方法返回头信息开始--------------");
				// for (int i = 0; i < header.length - 1; i++) {
				// System.out.print(header[i]);
				// }
				// System.out.println("--------------get方法返回头信息结束--------------");
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				response = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}
		return response;
	}

	/**
	 * @Title: getReqUrl4Get
	 * @Description: get类方法请求地址封装(客户端统一后台)
	 * @param :@param
	 *            methodPath
	 * @param :@param
	 *            paramMap
	 * @param :@return
	 * @return String 返回类型
	 * @author qushengzhi
	 * @date Oct 23, 2012 4:13:43 PM
	 */
	@SuppressWarnings("unchecked")
	public static String getReqUrl4Get(String methodPath,
			Map<String, String> paramMap) {
		String reqUrl = "";
		// Constants.CLIENT_UNIFIED_BACKGROUND_ADDRESS
		// + methodPath + "?";
		if (paramMap != null) {
			Set set = paramMap.keySet();
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				String key = (String) iter.next();
				String value = paramMap.get(key);
				if (StringUtils.isBlank(value))
					value = "";
				reqUrl = reqUrl + "&" + key + "=" + value;
			}
			int position = reqUrl.indexOf("?");
			String beginStr = reqUrl.substring(0, position + 1);
			String endStr = reqUrl.substring(position + 2);
			reqUrl = beginStr + endStr;
		}
		// logger.info("get方法请求地址：" + reqUrl);
		return reqUrl;
	}

	/**
	 * @Title: getReqUrl4Post
	 * @Description: 封装请求地址post(客户端统一后台)
	 * @param :@param
	 *            methodPath
	 * @param :@return
	 * @return String 返回类型
	 * @author qushengzhi
	 * @date Oct 24, 2012 3:09:46 PM
	 */
	public static String getReqUrl4Post(String methodPath) {
		String reqUrl = "";
		// String reqUrl = Constants.CLIENT_UNIFIED_BACKGROUND_ADDRESS
		// + methodPath;
		logger.info("post请求地址:" + methodPath);
		return reqUrl;
	}
	/**
	 * @Title: send4PostNew 
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param :@param url
	 * @param :@param reqStr
	 * @param :@return
	 * @param :@throws Exception
	 * @return String    返回类型  
	 * @author 王恭尧
	 * @date 2014-4-25 下午04:10:36
	 */
	public static String send4PostNew(String url, String reqStr) throws Exception {
		String rspStr = null;// 返回字符串
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建post连接方法实例并设置参数
		 */
		PostMethod method = new PostMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 失败不重发
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
		
		// 设置表单信息
		if (reqStr != null)
			method.setRequestEntity(new StringRequestEntity(reqStr, null,
					CHARSET));
		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				// 打印响应头信息
//				 Header[] header = method.getResponseHeaders();
//				 System.out.println("--------------post方法返回头信息开始--------------");
//				 for (int i = 0; i < header.length - 1; i++) {
//				 System.out.print(header[i]);
//				 }
//				 System.out.println("--------------post方法返回头信息结束--------------");
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				rspStr = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}

		return rspStr;
	}
	
	/**
	 * @Title: send4Post 
	 * @Description: 提交httpPost表单请求
	 * @param :@param url
	 * @param :@param String 表单参数报文
	 * @param :@param headers  httpHeaders
	 * @param :@param timeOut  超时时间，为空则使用默认值
	 * @param :@return
	 * @param :@throws Exception
	 * @return String    返回类型  
	 * @author 蔡协鑫
	 * @date 2014年6月5日 上午10:57:04
	 */
	public static String send4PostForm(String url, String reqStr,Map<String,String> headers,Integer timeOut) throws Exception {
		String rspStr = null;// 返回字符串
		timeOut=timeOut==null?TIME_OUT:timeOut;
		/**
		 * 1.创建HttpClient实例并设置参数
		 */
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setParameter("http.protocol.content-charset",
				CHARSET);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(
				TIME_OUT);
		/**
		 * 2.创建post连接方法实例并设置参数
		 */
		PostMethod method = new PostMethod(url);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));// 失败不重发
		method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, TIME_OUT);
		// 设置公共请求信息
		method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		if(headers!=null){
			for(String key : headers.keySet()) {  
				method.addRequestHeader(key, headers.get(key));  
			}  
		}
		// 设置表单信息
		if (reqStr != null)
			method.setRequestEntity(new StringRequestEntity(reqStr, null,
					CHARSET));
	          
		/**
		 * 3.调用实例httpClient的executeMethod方法来执行method 实例
		 */
		InputStream in = null;
		BufferedReader buffer = null;
		try {
			int retcode = httpClient.executeMethod(method);
			if (retcode == HttpStatus.SC_OK) {
				StringBuffer temp = new StringBuffer();
				in = method.getResponseBodyAsStream();
				buffer = new BufferedReader(new InputStreamReader(in, CHARSET));
				for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
					temp = temp.append(tempstr);
				rspStr = temp.toString().trim();
			} else {
				throw new IOException("发送失败: retcode: " + retcode);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (buffer != null)
				buffer.close();
			if (in != null)
				in.close();
			if (method != null)
				method.releaseConnection();// 释放连接
		}

		return rspStr;
	}
	
	public static void main(String[] args) throws Exception {
		String url = "http://bnetforap.fj.bnet.cn/ASPInterfaceForBP/BuyAppInterface.ashx";
		String param="param";
		String content = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxSZXF1ZXN0PjxIZWFkPjxUcmFuc2FjdGlvbklEPjAwMDAwMTwvVHJhbnNhY3Rpb25JRD48VG9rZW4+N05obkx4d2V3Vi81U0JyU2YrWFFRVGlPUUpobnlDTWk8L1Rva2VuPjxTb3VyY2U+RUVDUDwvU291cmNlPjxBY2Nlc3NUb2tlbj42MzYxNkM2QzcyNjk2RTY3MjUyNDIzNDAyMTUxNDE0QTQ5NEYzMDM5MzYzNDMzMzI8L0FjY2Vzc1Rva2VuPjwvSGVhZD48Qm9keT48T3JkZXJBY3Rpb24+QVBQU1VCPC9PcmRlckFjdGlvbj48VXNlcklEPm1hc3RlckBmamlpY29tPC9Vc2VySUQ+PFBhc3N3b3JkPmFzZGFzZDwvUGFzc3dvcmQ+PFBheVR5cGU+MTwvUGF5VHlwZT48QXBwcyA+PEFwcEluZm8gQXBwSUQ9IjE0MDAwMDY4MDAwMDAwMDAwMDAwMDAwNiIgIE9mZmVySUQ9IjE0MDAwMTY5IiAgUmVhbE1vbmV5PSIxMCIgUmVuZXdUaW1lcyA9IjEiPjxQYXJhbWV0ZXIgTmFtZT0ibnVtIiAgVmFsdWU9IjEiIC8+PFBhcmFtZXRlciBOYW1lPSJMaWNlbnNlTnVtIiAgVmFsdWU9IjUiICAvPjwvQXBwSW5mbz48L0FwcHM+PC9Cb2R5PjwvUmVxdWVzdD4=";
		String resp = HttpSenderUtil.send4PostNew(url, param+"="+content);
		System.out.println(resp);
	}
}
